/*
 *
 * C++ MaJiang for 血流红中
 *
 * TuyooGame, 2021
 * zhouxin@tuyoogame.com
 *
 */
#include "mj.h"
#include "log.h"

vector<uint8_t> lz {35};

void 
test_ti() {
    //test tiles count & shape...
    vector<uint8_t> ts {3, 3, 3, 3, 4, 8, 8, 35, 35, 1, 1, 3, 31, 31};
    
    for(int i=0; i<1; i++) {
        Tiles *t = new Tiles(ts, lz);
        printf("lzn=%d %d %d\n", t->laizi_count, t->counter[WAN].n, t->counter[WAN].bucket[0]);
        printf("ishu====%d\n", t->isHu());
    }

    uint64_t shape = 113333L, laizi = 6L;
    MJHelper::searchPart(shape);
    shape = 121021101L, laizi = 5L;
    MJHelper::searchBu(laizi, shape); 
}

void 
test_copy_mfi() {
    MJ_CPG_INFO cpg;
    cpg.count = 0; 
    MJ_FX_INFO mfi;
    vector<uint8_t> t4 {11,11,12,12,13,13,14,14,15,15,16,16,17,17};
    assignMFI(&mfi, t4, lz, 0, WAN, &cpg);
    struct timeval tvs,tve;
    gettimeofday(&tvs,NULL);
    MJ_FX_INFO mfi_copy;
    for(int i=0; i<1000000; i++) {
        mfi_copy = mfi;
        mfi_copy.now_tile = (uint8_t) i;
    }
    gettimeofday(&tve,NULL);
    uint64_t span = (uint64_t)((tve.tv_sec-tvs.tv_sec)*1000000 + (tve.tv_usec-tvs.tv_usec));
    cout << span << endl;
}

void
test_check_allmj_ishu(const char *fpath) {
    struct timeval tvs,tve;
    gettimeofday(&tvs,NULL);
    ifstream fin(fpath);
    uint64_t lidx = 0;
    uint64_t hucnt = 0;
    string l;
    uint64_t span; 

    Tiles *t = new Tiles();

    while(getline(fin, l)) {

        if(lidx % 100000 == 0) {
            gettimeofday(&tve,NULL);
            span = (uint64_t)((tve.tv_sec-tvs.tv_sec)*1000000 + (tve.tv_usec-tvs.tv_usec));
            printf("time=%" PRIu64 "\n", span);
            printf("process %" PRIu64 " hu %" PRIu64 "\n", lidx, hucnt);
        }

        vector<uint8_t> lts;
        for(unsigned i=0; i<l.size(); i++) {
            char c = l.c_str()[i];
            if(c<='I' and c>='A') lts.push_back(c - 'A' + 11);
            if(c<='i' and c>='a') lts.push_back(c - 'a' + 1);
        }
        sort(lts.begin(), lts.end());

        t->assign(lts, lz);
        bool ih = t->isHu();
        if(ih) {
            cout << l << endl;
            hucnt++;
        }

        /*if(lidx>=1000 && lidx<=2000)
            printf("%s %d\n", l.c_str(), ih);*/
        //if(lidx==10000) break;

        lidx++;
    }
    delete t;
    gettimeofday(&tve,NULL);
    span = (uint64_t)((tve.tv_sec-tvs.tv_sec)*1000000 + (tve.tv_usec-tvs.tv_usec));
    printf("time=%" PRIu64 "\n", span);
}

void
test_debug_xueliuhz(const char *fpath) {
    XueLiuHZCard *xc = new XueLiuHZCard(); 
    ifstream fin(fpath);
    string l;
    while(getline(fin, l)) {
        snprintf(xc->input_buffer, 1024, "%s", l.c_str());
        xc->loadInput();
        uint64_t totalet = 0;
        uint32_t et;
        et = xc->hasTing();
        totalet += et;
        xc->dumpOutput();
        xc->printHuResult();
        printf("time=%lfs, %u\n", totalet/1000000.0, et);
        break;
    }
}

void
test_check_xueliuhz() {
    XueLiuHZCard *xc = new XueLiuHZCard(); 
    //MJ_CPG_INFO cpg;
    //uint8_t nt;

    /*
    //七对...
    cpg.count = 0; 
    nt = 35;
    vector<uint8_t> tt {11, 11, 12, 12, 13, 13, 1, 1, 2, 2, 3, 3, 3};
    //vector<uint8_t> tt {1, 1, 1, 1, 35, 35, 2, 2, 2, 3, 3, 3, 5};
    */
    
    /*
    cpg.count = 1;
    //MJ_CPG指针,tile, com1~com4, from_seat, CPG_TYPE, CPG_SUBTYPE(缺省为CPG_NA)
    //注意：对于3张碰牌，com4填0
    assignCPG(&cpg.cpgs[0], 16, 16, 16, 16, 0, 1, PENG);
    nt = 35;
    vector<uint8_t> tt {11, 11, 11, 5, 6, 7, 8, 19, 19, 19};
    */

    /*
    cpg.count = 0;
    nt = 35;
    vector<uint8_t> tt {12,12,12,13,13,13,14,14,14,14,18,18,35}; //无6条 hu
    */

    //BUG.....
    //633097.35.13.11.12.12.13.15.15.16.17.19.35.35.35.35.0.35.2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.0
    //7776.3.13.1.1.1.1.3.3.3.3.4.8.8.35.35.0.35.2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.0
    //108.21.13.11.23.23.27.27.11.12.13.14.22.23.27.35.0.35.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.0
    //18951.35.13.11.12.13.14.15.16.17.18.19.35.2.7.8.0.35.2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.0
    //15.35.13.6.6.23.27.29.6.7.8.23.27.28.29.35.0.35.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.0
    //686.5.7.5.29.29.4.5.29.35.0.0.0.0.0.0.0.35.1.2.21.21.21.21.0.2.1.1.25.25.25.25.0.2.1.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.0
    //2798560.35.10.12.16.17.18.18.35.35.16.12.16.0.0.0.0.35.2.1.15.15.15.15.15.0.2.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0
    //noSplitShape死循环问题...
    //2128909.27.13.22.23.27.27.29.29.29.29.35.27.22.23.27.0.35.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.0
    snprintf(xc->input_buffer, 1024, "2798560.35.10.12.16.17.18.18.35.35.16.12.16.0.0.0.0.35.2.1.15.15.15.15.15.0.2.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.0");
    xc->loadInput();
    /*
    cpg.count = 1;
    assignCPG(&cpg.cpgs[0], 15, 15, 15, 15, 15, 0, GANG, BU_GANG);
    nt = 35;
    vector<uint8_t> tt {12, 16, 17, 18, 18, 35, 35, 16, 12, 16};
    //nt = 13;
    //vector<uint8_t> tt {12, 16, 35, 18, 18, 35, 35, 16, 12, 16};
    xc->assign(tt, nt, lz, TONG, &cpg);
    */
#if 0
    //for debug...
    vector<vector<MJ_FANXING>> fdata {};
    xc->getFanXing(&xc->mfi_raw, fdata);
    return;
#endif

    uint64_t totalet = 0;
    uint32_t et;
    for(int i=0; i<1; i++) {
        et = xc->hasTing();
        totalet += et;
        xc->dumpOutput();
        xc->printHuResult();
    }
    printf("time=%lfs, %u\n", totalet/1000000.0, et);

    xc->dumpInput();
    printf("%s\n", xc->input_buffer);
    //再解析再dump，测试是否正确...
    xc->loadInput();
    xc->dumpInput(false);
    printf("%s\n", xc->input_buffer);

#if 0
    //一条龙...
    //vector<uint8_t> t2 {11, 11, 12, 13, 14, 14, 15, 16, 17, 18, 19, 35, 35};
    //xc->assign(t2, 35, lz, TONG, &cpg);
    //xc->getFanXing(t2, 35);

    //绿一色
    //vector<uint8_t> t2 {12,12,12,13,13,13,14,14,14,14,18,18,35,35}; //无6条 hu
    //vector<uint8_t> t2 {12,12,12,13,13,13,14,14,14,16,18,35,35,35}; //lz补6条成刻 hu
    //vector<uint8_t> t2 {12,12,12,13,13,13,14,14,14,14,16,18,35,35}; //lz补6条成刻 no hu
    vector<uint8_t> t2 {12,12,12,13,13,13,14,14,14,16,18,18,18,35}; //lz补6条成对 hu
    //vector<uint8_t> t2 {12,12,12,13,13,13,14,14,16,16,16,16,18,35}; //lz补6条成对 no hu
    assignMFI(&mfi, t2, lz, 0, WAN, &cpg);
    int8_t hu = fx_LvYiSe(&mfi);
    printf("LvYiSe hu...%d\n", hu);

    //九莲宝灯
    vector<uint8_t> t3 {11,11,35,35,13,14,15,16,17,18,19,19,19};
    assignMFI(&mfi, t3, lz, 11, WAN, &cpg);
    hu = fx_JiuLianBaoDeng(&mfi);
    printf("JiuLianBaoDeng hu...%d\n", hu);

    //连七对
    vector<uint8_t> t4 {11,11,12,12,13,13,14,14,15,15,16,16,17,17};
    assignMFI(&mfi, t4, lz, 0, WAN, &cpg);
    MJ_FX_INFO mfi_copy = mfi;
    hu = fx_LianQiDui(&mfi_copy);
    printf("LianQiDui hu...%d\n", hu);

    //带幺九
    vector<uint8_t> t5 {11,12,13,19,18,17,11,11,1,2,3,1,2,3};
    assignMFI(&mfi, t5, lz, 0, TONG, &cpg);
    hu = fx_DaiYaoJiu(&mfi);
    printf("DaiYaoJiu hu...%d\n", hu);

    //暗刻
    //vector<uint8_t> t6 {1,1,1,2,2,2,3,3,3,4,35,35,5,5};
    vector<uint8_t> t6 {1,1,1,1,35,35,2,2,2,3,3,3,6,6};
    Tiles ti;
    ti.assign(t6, lz);
    printf("ti shape = %llu\n", ti.shape_noz);
    ti.isHu();

    /*
    auto vv = xc->getQueTiles();
    for(size_t i=0; i<vv.size(); i++)
        printf("%d\n", vv[i]);

    vv = xc->getTingTilesUniq();
    for(size_t i=0; i<vv.size(); i++)
        printf("%d\n", vv[i]);

    vector<uint8_t> vs = xc->getLeftTiles();
    for(size_t i=0; i<vs.size(); i++)
        printf("vs..%d\n", vs[i]);
    */
#endif
}

int 
main() {
    log_set_level(LOG_DEBUG);

    test_ti();
    //test_check_allmj_ishu("../hu_dict/hu.txt");
    test_debug_xueliuhz("./client_input.txt");

    return 0;
}
